﻿using System;

namespace MicroContainer.CompileTime
{
   /// <summary>
   /// Type mapping definition.
   /// </summary>
   public sealed class TypeMappingDef
   {
      /// <summary>
      /// Gets type which should be mapped.
      /// </summary>
      public Type From { get; private set; }
      /// <summary>
      /// Gets type to which mapping leads.
      /// </summary>
      public Type To { get; private set; }
      /// <summary>
      /// Gets the factory method to use to produce type instance.
      /// </summary>
      public Delegate FactoryMethod { get; private set; }
      /// <summary>
      /// Gets optional mapping name.
      /// </summary>
      public string Name { get; private set; }
      /// <summary>
      /// Gets unique id of this mapping.
      /// </summary>
      public Guid UniqieId { get; private set; }
      /// <summary>
      /// Gets the instance cration mode.
      /// </summary>
      public InstantiationMode Mode { get; private set; }

      /// <summary>
      /// Creates new <see cref="TypeMappingDef"/> instance.
      /// </summary>
      /// <param name="from">From type.</param>
      /// <param name="to">To type.</param>
      /// <param name="name">Optional name.</param>
      /// <param name="mode">Instance creation mode.</param>
      public TypeMappingDef(Type from, Type to, string name, InstantiationMode mode)
      {
         if (from == null)
         {
            throw new ArgumentNullException("from");
         }
         if (to == null)
         {
            throw new ArgumentNullException("to");
         }
         From = from;
         To = to;
         Name = name;
         UniqieId = Guid.NewGuid();
         Mode = mode;
      }

      /// <summary>
      /// Creates new <see cref="TypeMappingDef"/> instance.
      /// </summary>
      /// <param name="from">From type.</param>
      /// <param name="factoryMethod">The factory method to use to produce type instance.</param>
      /// <param name="name">Optional name.</param>
      /// <param name="mode">Instance creation mode.</param>
      public TypeMappingDef(Type from, Delegate factoryMethod, string name, InstantiationMode mode)
      {
         if (from == null)
         {
            throw new ArgumentNullException("from");
         }
         if (factoryMethod == null)
         {
            throw new ArgumentNullException("factoryMethod");
         }
         From = from;
         FactoryMethod = factoryMethod;
         Name = name;
         UniqieId = Guid.NewGuid();
         Mode = mode;
      }
   }
}
